package xtrace

import (
	"context"
	"fmt"
	"gitee.com/go-mid/infra/xcontext"
	"github.com/opentracing/opentracing-go/ext"
	"net/http"
	"strconv"

	"github.com/opentracing/opentracing-go"
)

// TraceHTTPRequest is a helper function for injecting trace-related context into HTTP headers.
func TraceHTTPRequest(ctx context.Context, req *http.Request) error {
	fun := "TraceHttpRequest-->"
	if ctx == nil {
		return fmt.Errorf("%s got nil context", fun)
	}

	if req == nil {
		return fmt.Errorf("%s got nil request", fun)
	}

	if span := opentracing.SpanFromContext(ctx); span != nil {
		return opentracing.GlobalTracer().Inject(
			span.Context(),
			opentracing.HTTPHeaders,
			opentracing.HTTPHeadersCarrier(req.Header))
	}
	return fmt.Errorf("%s got nil span", fun)
}

func GetHttpContext(r *http.Request) context.Context {
	carrier := opentracing.HTTPHeadersCarrier(r.Header)
	clientContext, err := opentracing.GlobalTracer().Extract(opentracing.HTTPHeaders, carrier)
	rpcMethodName := r.RequestURI
	var serverSpan opentracing.Span
	if err == nil {
		serverSpan = opentracing.GlobalTracer().StartSpan(
			rpcMethodName, ext.RPCServerOption(clientContext))
	} else {
		serverSpan = opentracing.GlobalTracer().StartSpan(rpcMethodName)
	}

	ctx := opentracing.ContextWithSpan(r.Context(), serverSpan)
	if r == nil {
		return ctx
	}
	if r.Header != nil {
		SrcStr := r.Header.Get(xcontext.ContextKeySrc)
		if len(SrcStr) > 0 {
			Src, _ := strconv.ParseInt(SrcStr, 10, 64)
			ctx = xcontext.WithSource(ctx, int32(Src))
		}
		Caller := r.Header.Get(xcontext.ContextKeyCaller)
		if len(Caller) > 0 {
			ctx = xcontext.WithCaller(ctx, Caller)
		}
	}
	return ctx
}
